package com.iwhalecloud.bss.kite.cucc.order.accept.constructor.inst;

import com.google.common.collect.Sets;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.TableConsts;
import com.iwhalecloud.bss.kite.common.util.SeqUtils;
import com.iwhalecloud.bss.kite.cucc.order.util.AcceptUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferDetailCache;
import com.iwhalecloud.bss.kite.dataservice.entity.inst.OfferObjInstRel;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferDetail;
import com.iwhalecloud.bss.kite.dataservice.mapper.inst.OfferObjInstRelMapper;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.graph.impl.RelEdge;
import com.iwhalecloud.bss.kite.manager.util.RelTypeUtils;
import com.iwhalecloud.bss.kite.order.client.dto.OrderRequest;
import com.ztesoft.bss.base.staticdata.CoreDataPublic;
import com.ztesoft.bss.common.util.SpringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

/**
 * 销售品包含对象实例构造器
 * @version 1.0
 */
@Component
public class OfferObjInstRelConstructor extends RelConstructor<OfferObjInstRel> {

    @Override
    public String getTableName() {
        return TableConsts.OfferObjInstRel.getTableName();
    }

    @Override
    public OfferObjInstRel newInst(OrderRequest orderRequest, RelEdge relEdge, String offerObjInstRelId) {
        if (!ObjectUtils.allNotNull(orderRequest, relEdge)) {
            return null;
        }

        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(orderRequest.getCustId(),
            relEdge.getSourceInstId());

        String offerInstId = relEdge.getSourceInstId();
        String compInstId = Optional.ofNullable(offerInst).map(KiteOfferInst::getOfferInstId).orElse(null);
        String mCompInstId = relEdge.getTargetInstId();
        String instanceId = relEdge.getTargetInstId();
        String objId = relEdge.getTargetInstId();

        if (Objects.equals(InstType.ADDITIONAL_OFFER_INST, relEdge.getSourceInstType())) {
            compInstId = querySceneInstService.getAdditionalOfferInstCompInstId(orderRequest.getCustId(),
                relEdge.getSourceInstId());
        }

        if (Objects.equals(RelType.OFFER_OBJ_REL_TYPE_1000, relEdge.getRelType())) {
            if (Objects.equals(InstType.PROD_INST, relEdge.getTargetInstType())) {
                // 销售品实例和接入产品实例关系，mCompInstId是接入产品实例对应的基础销售品实例id
                KiteProdInst prodInst = querySceneInstService.getProdInst(orderRequest.getCustId(),
                    relEdge.getTargetInstId());
                mCompInstId = Optional.ofNullable(prodInst).map(KiteProdInst::getOfferInstId).orElse(null);
            }
        }
         else if (Objects.equals(RelType.OFFER_OBJ_REL_TYPE_170000, relEdge.getRelType())) {
            mCompInstId = null;
         }

        fillRelEdge(relEdge, orderRequest.getCustId());

        String objType = RelTypeUtils.getRelTypeCode(relEdge);
        OfferObjInstRel offerObjInstRel = new OfferObjInstRel();
        offerObjInstRel.setOfferObjInstRelId(offerObjInstRelId);
        offerObjInstRel.setOwnerCustId(orderRequest.getCustId());
        offerObjInstRel.setProdCompRoleCd(relEdge.getRoleId());
        offerObjInstRel.setObjType(objType);
        offerObjInstRel.setLanId(orderRequest.getLanId());
        offerObjInstRel.setInstanceId(instanceId);
        offerObjInstRel.setCompInstId(compInstId);
        offerObjInstRel.setCreateStaff(orderRequest.getStaffId());
        offerObjInstRel.setDetailId(relEdge.getDetailId());
        offerObjInstRel.setMcompInstId(mCompInstId);
        offerObjInstRel.setOfferInstId(offerInstId);
        offerObjInstRel.setObjId(objId);
        offerObjInstRel.setRoleId(relEdge.getRoleId());

        fillNewOfferObjInstRel(offerObjInstRel);
        return offerObjInstRel;
    }

    @Override
    public OfferObjInstRel getInstRel(String offerInstId, String objId, String objType, String custId) {
        Example example = new Example(OfferObjInstRel.class);
        example.createCriteria().andEqualTo("offerInstId", offerInstId).andEqualTo("objType", objType)
            .andEqualTo("instanceId", objId);

        OfferObjInstRelMapper mapper = SpringUtil.getBean(OfferObjInstRelMapper.class);
        List<OfferObjInstRel> offerObjInstRels = mapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(offerObjInstRels)) {
            OfferObjInstRel offerObjInstRel = offerObjInstRels.get(0);
            if (Objects.equals(ActionType.A.name(), offerObjInstRel.getActionType())) {
                offerObjInstRel.setNewActionType(ActionType.K.name());
            }
            return offerObjInstRel;
        }

        return null;
    }

    /**
     * 补充边的roleId和detailId
     * @param relEdge
     * @param custId
     */
    public void fillRelEdge(RelEdge relEdge, String custId) {
        if (Objects.isNull(relEdge) || StringUtils.isNoneBlank(relEdge.getRoleId(), relEdge.getDetailId())) {
            return;
        }

        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteOfferInst offerInst = querySceneInstService.getOfferInst(custId, relEdge.getSourceInstId());

        String offerId = Optional.ofNullable(offerInst).map(KiteOfferInst::getOfferId).orElse("");
        Set<String> objTypes = Sets.newHashSet(RelTypeUtils.getRelTypeCode(relEdge));
        String objId = "-1";

        if (Objects.equals(RelType.OFFER_OBJ_REL_TYPE_1000, relEdge.getRelType())) {
            KiteInst inst = querySceneInstService.getKiteInst(custId, relEdge.getTargetInstType(),
                relEdge.getTargetInstId());
            objId = Optional.ofNullable(inst).map(KiteInst::getSpecId).orElse("");

            if (Objects.equals(InstType.GIFT_OFFER_INST, relEdge.getSourceInstType())
                && AcceptUtils.isOfferInst(relEdge.getTargetInstType())) {
                // 礼包和销售品的包含关系在offer_obj_rel配置的rel_type可能100000，这里做兼容处理
                objTypes.clear();
                objTypes.add(RelType.OFFER_OBJ_REL_TYPE_110000.getCode());
                objTypes.add(RelType.OFFER_OBJ_REL_TYPE_1000.getCode());
            }
        }

        OfferDetail offerDetail = getOfferDetail(offerId, objTypes, objId);
        if (StringUtils.isBlank(relEdge.getRoleId())) {
            relEdge.setRoleId(Optional.ofNullable(offerDetail).map(OfferDetail::getRoleId).orElse("-1"));
        }

        if (StringUtils.isBlank(relEdge.getDetailId())) {
            relEdge.setDetailId(Optional.ofNullable(offerDetail).map(OfferDetail::getDetailId).orElse("-1"));
        }
    }

    /**
     * 获取销售品明细
     * @param offerId
     * @param objTypes
     * @param objId
     * @return
     */
    public OfferDetail getOfferDetail(String offerId, Set<String> objTypes, String objId) {
        if (StringUtils.isAnyBlank(offerId, objId) || CollectionUtils.isEmpty(objTypes)) {
            return null;
        }

        List<OfferDetail> offerDetails = OfferDetailCache.get(offerId);
        for (OfferDetail offerDetail : offerDetails) {
            if (objTypes.contains(offerDetail.getObjType()) && Objects.equals(objId, offerDetail.getObjId())) {
                return offerDetail;
            }
        }

        return null;
    }

    /**
     * 补充新增的销售品包含对象实例属性
     * @param offerObjInstRel
     */
    public void fillNewOfferObjInstRel(OfferObjInstRel offerObjInstRel) {
        if (Objects.isNull(offerObjInstRel)) {
            return;
        }

        Date now = new Date();
        if (StringUtils.isBlank(offerObjInstRel.getOfferObjInstRelId())) {
            offerObjInstRel.setOfferObjInstRelId(SeqUtils.getNext(TableConsts.OfferObjInstRel));
        }
        offerObjInstRel.setActionType(ActionType.A.name());
        offerObjInstRel.setStateCd(KeyConsts.STATE_ONWAY);
        offerObjInstRel.setCreateDate(now);
        offerObjInstRel.setProdTypeCd(KeyConsts.PROD_TYPE_CD_01);
        offerObjInstRel.setOfferProdInstRelId(offerObjInstRel.getOfferObjInstRelId());
        offerObjInstRel.setRoleCd("-1");
        offerObjInstRel.setEffDate(now);
        offerObjInstRel.setExpDate(AcceptUtils.getDefaultExpDate());
        offerObjInstRel.setStatusCd(CoreDataPublic.PUB_C_0001_1200);
        offerObjInstRel.setUpdateDate(now);
        offerObjInstRel.setLastOrderItemId("-1");
    }
}
